package com.mall.pay.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.json.JSONUtil;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.easysdk.factory.Factory;
import com.mall.api.pay.dto.PayDTO;
import com.mall.pay.config.AliPayConfig;
import com.mall.pay.domain.dto.AliPayDTO;
import com.mall.pay.domain.dto.NotifyDTO;
import com.mall.pay.domain.po.Order;
import com.mall.pay.domain.po.PayInfo;
import com.mall.pay.domain.po.PayInfoResult;
import com.mall.pay.mapper.PayInfoMapper;
import com.mall.pay.service.IPayService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class PayServiceImpl implements IPayService {

    @Resource
    AliPayConfig aliPayConfig;

    @Autowired
    private PayInfoMapper payInfoMapper;

    @Override
    public String pay(PayDTO payDTO) throws AlipayApiException {

        AlipayClient alipayClient = new DefaultAlipayClient(aliPayConfig.getGATEWAY_URL(), aliPayConfig.getAppId(),
                aliPayConfig.getAppPrivateKey(), aliPayConfig.getFORMAT(),
                aliPayConfig.getCHARSET(), aliPayConfig.getAlipayPublicKey(), aliPayConfig.getSIGN_TYPE());

        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
        request.setNotifyUrl(aliPayConfig.getNotifyUrl());

        // 暂时用时间戳代替订单号
        if (payDTO.getOut_trade_no() == null) {
            payDTO.setOut_trade_no(String.valueOf(System.currentTimeMillis()));
        }
        //TODO
        //创建支付单
        PayInfo payInfo = PayInfo.builder()
                .payId(Long.valueOf(payDTO.getOut_trade_no()))
                .userId(payDTO.getUserId())
                .orderIds(payDTO.getOrderIds())
                .payStatus(0)
                .payAmount(payDTO.getTotal_amount())
                .version(1)
                .build();
        // 保存支付单,未支付状态, 在回调成功之后修改为已支付
        payInfoMapper.save(payInfo);

        AliPayDTO aliPayDTO = AliPayDTO.builder()
                .out_trade_no(payDTO.getOut_trade_no())
                .total_amount(payDTO.getTotal_amount())
                .subject(payDTO.getSubject())
                .build();

        log.info("发起支付,参数为:{}", JSONUtil.toJsonStr(aliPayDTO));
        request.setBizContent(JSONUtil.toJsonStr(aliPayDTO));
        // 调用SDK生成表单
        return alipayClient.pageExecute(request).getBody();
    }

    @Override
    public String payNotify(NotifyDTO notifyDTO) throws Exception {
        Map<String, String> params = notifyDTO.getParams();

        // 检查交易状态 和 支付宝验签
        if (!"TRADE_SUCCESS".equals(notifyDTO.getTradeStatus()) || !Factory.Payment.Common().verifyNotify(params)) {
            return "fail";
        }
        // 验签通过，处理业务逻辑
        String outTradeNo = notifyDTO.getOutTradeNo();
        // 根据支付单号获取支付单,更新支付单状态
        PayInfo payInfo = payInfoMapper.getByPayId(Long.valueOf(outTradeNo));
        payInfo.setPayStatus(1);
        log.info("支付成功: {}", payInfo);

        //TODO
        // 确认成功之后修改支付单
        //mysql支付单改为已支付状态
        payInfoMapper.update(payInfo);
        //并且远程调用订单业务修改订单状态

        return "success";
    }


    //TODO 待实现接口
    @Override
    public PayInfo getByPayId(Long payId) {
        return null;
    }

    @Override
    public void paySuccess(PayInfoResult payInfoResult, List<Long> orderIds) {

    }

    @Override
    public Integer getPayStatusByOrderIds(String orderIds) {
        return 0;
    }

    @Override
    public Integer isPay(String orderIds, Long userId) {
        return 0;
    }
}
